import type {AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig} from "axios"
import axios from "axios"
import type {MyRequestConfig} from "./type";


class Request {
    instance: AxiosInstance;

    constructor(config: MyRequestConfig, hasGlobalInterceptors= false) {
        this.instance = axios.create(config)

        if (hasGlobalInterceptors){
            Request.addRequestInterceptor(this.instance, config)
            Request.addResponseInterceptor(this.instance)
        }

        // 只有当此实例的config中存在请求拦截器和响应拦截器存在时，才添加拦截器，起到实例级拦截的作用
        this.instance.interceptors.request.use(
            config.interceptors?.reqSuccessCallback,
            config.interceptors?.reqFailCallback
        )
        this.instance.interceptors.response.use(
            config.interceptors?.resSuccessCallback,
            config.interceptors?.resFailCallback
        )
    }

    request<T = any>(config: MyRequestConfig<T>) {
        // 单次请求拦截
        if (config.interceptors?.reqSuccessCallback) {
            config = config.interceptors.reqSuccessCallback(config as InternalAxiosRequestConfig)
        }

        return new Promise<T>((resolve, reject) => {
            // 调用axios的原生request方法
            this.instance.request<any, T>(config).then(res => {
                if (config.interceptors?.resSuccessCallback) {
                    res = config.interceptors?.resSuccessCallback(res)
                }
                resolve(res)
            }).catch(err => {
                reject(err)
            })
        })
    }

    get<T = any>(config: MyRequestConfig<T>) {
        return this.instance.request({
            ...config,
            method: "get"
        })
    }

    post<T = any>(config: MyRequestConfig<T>) {
        return this.instance.request({
            ...config,
            method: "post"
        })
    }

    put<T = any>(config: MyRequestConfig<T>) {
        return this.instance.request({
            ...config,
            method: "put"
        })
    }

    delete<T = any>(config: MyRequestConfig<T>) {
        return this.instance.request({
            ...config,
            method: "delete"
        })
    }

    patch<T = any>(config: MyRequestConfig<T>) {
        return this.instance.request({
            ...config,
            method: "patch"
        })
    }

    /**
     * 添加请求拦截器
     * @param instance Axios实例
     * @param config 请求配置
     */
    static addRequestInterceptor(instance: AxiosInstance, config: any) {
        instance.interceptors.request.use(
            (config) => {
                console.log("全局请求拦截成功", config)
                return config
            },
            (err) => {
                console.log("请求失败")
            }
        )
    }

    /**
     * 添加响应拦截器
     * @param instance Axios实例
     */
    static addResponseInterceptor(instance: AxiosInstance) {
        instance.interceptors.response.use(
            (res) => {
                console.log("全局响应拦截成功", res)
                return res
            },
            (err) => {
                console.log("响应失败")
            }
        )
    }
}

export default Request;
